package locks;

import java.util.concurrent.atomic.AtomicReference;

public class CLHLock implements SimpleLock {

    private AtomicReference<QNode> tail;

    private ThreadLocal<QNode> myPred;

    private ThreadLocal<QNode> myNode;

    public CLHLock() {
        this.tail = new AtomicReference<>(new QNode());
        this.myPred = new ThreadLocal<>();
        this.myNode = ThreadLocal.withInitial(QNode::new);
    }

    @Override
    public void lock() {
        QNode qNode = myNode.get();
        qNode.locked = true;
        // 将tail节点置为thread-local中的节点
        QNode pred = tail.getAndSet(qNode);
        // 拿到队列中前驱节点
        myPred.set(pred);
        while (pred.locked) {
        }
    }

    @Override
    public void unlock() {
        QNode qNode = myNode.get();
        qNode.locked = false;

        myNode.set(myPred.get());
    }

    private static class QNode {
        private volatile boolean locked = false;
    }
}

